package com.security.securityproject;

import android.app.IntentService;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Base64;

import com.security.SecutiryTools.Aes;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class KeyService extends IntentService {

	public static final String REPORT = "report";
	public static final String PASSWORD = "password";
	public static final String DURATION = "duration";
    public static final String IMEI = "imei";
	public static final String NOTIFICATION = "com.security.securityproject";
    private Socket socket;
    private static int systembars;
    private static final int SERVERPORT = 6000;
    private static final String SERVER_IP = "192.168.0.13";


    public KeyService() {
		super("KeyService");
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onHandleIntent(Intent intent) {


        InetAddress serverAddr = null;
        Bundle bundle = intent.getExtras();
        String password = bundle.getString(PASSWORD);
        String device_id = bundle.getString(IMEI);
        registerReceiver(receiver2, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION));
        BigInteger primeNumber,base,A,B,b,K;

        String buffer;

        while(systembars<3){
            try {
                Thread.sleep(2000);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            serverAddr = InetAddress.getByName(SERVER_IP);
            socket = new Socket(serverAddr, SERVERPORT);

            PrintWriter out = new PrintWriter(socket.getOutputStream(),
                 true);
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            buffer = in.readLine();
            primeNumber= new BigInteger(buffer);


            buffer = in.readLine();
            base=  new BigInteger(buffer);


            buffer= in.readLine();
            A=  new BigInteger(buffer);
             b= BigInteger.probablePrime(64,new Random());

            B= base.modPow(b,primeNumber);
            out.print(B.toString() + "\n");

            K= A.modPow(b,primeNumber);

            byte[] bytesOfMessage = K.toByteArray();
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] thedigest = md.digest(bytesOfMessage);


            out.print(Aes.encrypt("challengeMe",thedigest));
            out.flush();

            out.print(Aes.encrypt(device_id,thedigest));
            out.flush();
            int duration;
            String oneTimePass="";

            buffer = in.readLine();



            if(Aes.decrypt(buffer,thedigest).equals("valid")) {

            String hashvalue=device_id+password;
                buffer = in.readLine();
                System.out.println(Aes.decrypt(buffer,thedigest));
                //System.out.println("counter   "+buffer);
                for(int i=0;i< Integer.parseInt(Aes.decrypt(buffer,thedigest));i++){
                hashvalue=computeSHAHash(hashvalue);
                }
                System.out.println(hashvalue);
                out.print(Aes.encrypt(hashvalue,thedigest));
                out.flush();

                buffer=in.readLine();
                if(buffer.equals("error")){
                    publishResults("",0,in.readLine());
                }else if(Aes.decrypt(buffer,thedigest).equals("exist")) {
                    buffer=in.readLine();
                oneTimePass=Aes.decrypt(buffer,thedigest);
                    buffer=in.readLine();
                duration=Integer.parseInt(Aes.decrypt(buffer,thedigest));
                    publishResults(oneTimePass,duration,"exist");


                }else {

                    oneTimePass = Aes.decrypt(buffer,thedigest);
                    System.out.println("pass    "+oneTimePass);
                    buffer=in.readLine();
                    System.out.println("duration   "+buffer);

                    duration = Integer.parseInt(Aes.decrypt(buffer,thedigest));
                    publishResults(oneTimePass,duration,"ok");
                } }
            else {
                buffer=in.readLine();
                publishResults("",0,Aes.decrypt(buffer,thedigest));
            }


        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }  catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        unregisterReceiver(receiver2);
        stopSelf();
    }

	private void publishResults(String password,int duration,String report) {
		Intent intent = new Intent(NOTIFICATION);
		intent.putExtra(REPORT, report);
		intent.putExtra(PASSWORD, password);
		intent.putExtra(DURATION,duration);
		sendBroadcast(intent);
	}



    private static String convertToHex(byte[] data) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            int halfbyte = (data[i] >>> 4) & 0x0F;
            int two_halfs = 0;
            do {
                if ((0 <= halfbyte) && (halfbyte <= 9))
                    buf.append((char) ('0' + halfbyte));
                else
                    buf.append((char) ('a' + (halfbyte - 10)));
                halfbyte = data[i] & 0x0F;
            } while(two_halfs++ < 1);
        }
        return buf.toString();
    }


    public String computeSHAHash(String password)
    {
        String SHAHash = null;

        MessageDigest mdSha1 = null;
        try
        {
            mdSha1 = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException e1) {

        }
        try {
            mdSha1.update(password.getBytes("ASCII"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        byte[] data = mdSha1.digest();

            SHAHash =convertToHex(data);


        return SHAHash;
    }



//    public static byte[] encrypt(String plainText, byte[] encryptionKey) throws Exception {
//        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
//        SecretKeySpec key = new SecretKeySpec(encryptionKey, "AES");
//        cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV.getBytes("UTF-8")));
//        return cipher.doFinal(plainText.getBytes("UTF-8"));
//    }
//
//    public static String decrypt(byte[] cipherText, byte[] encryptionKey) throws Exception {
//        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
//        SecretKeySpec key = new SecretKeySpec(encryptionKey, "AES");
//        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV.getBytes("UTF-8")));
//        return new String(cipher.doFinal(cipherText), "UTF-8");
//    }







    BroadcastReceiver receiver2=new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            WifiManager wifimanager = (WifiManager) getSystemService(WIFI_SERVICE);
            int numberOfLevels=5;
            WifiInfo wifiInfo = wifimanager.getConnectionInfo();
            int level=wifimanager.calculateSignalLevel(wifiInfo.getRssi(), numberOfLevels);
            systembars=level;
            System.out.println("Reciever Bars =" +level);

        }
    };


}
